/*
 * 
 * 
 * 
 */
package com.hboxs.asl.controller.admin;

import com.hboxs.asl.ExcelView;
import com.hboxs.asl.Message;
import com.hboxs.asl.Pageable;
import com.hboxs.asl.entity.Coupon;
import com.hboxs.asl.entity.CouponCode;
import com.hboxs.asl.entity.Product;
import com.hboxs.asl.entity.ProductCategory;
import com.hboxs.asl.service.*;
import com.hboxs.asl.util.FreemarkerUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Controller - 优惠券
 */
@Controller("adminCouponController")
@RequestMapping("/asl-admin/coupon")
public class CouponController extends BaseController {

    @Resource(name = "couponServiceImpl")
    private CouponService couponService;
    @Resource(name = "couponCodeServiceImpl")
    private CouponCodeService couponCodeService;
    @Resource(name = "adminServiceImpl")
    private AdminService adminService;
    @Resource(name = "productCategoryServiceImpl")
    private ProductCategoryService productCategoryService;
    @Resource(name = "productServiceImpl")
    private ProductService productService;

    /**
     * 检查价格运算表达式是否正确
     */
    @RequestMapping(value = "/check_price_expression", method = RequestMethod.GET)
    public
    @ResponseBody
    boolean checkPriceExpression(String priceExpression) {
        if (StringUtils.isEmpty(priceExpression)) {
            return false;
        }
        try {
            Map<String, Object> model = new HashMap<String, Object>();
            model.put("quantity", 111);
            model.put("price", new BigDecimal(9.99));
            new BigDecimal(FreemarkerUtils.process("#{(" + priceExpression + ");M50}", model));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 添加
     */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add(ModelMap model) {
        model.addAttribute("productCategories", productCategoryService.findAll());
        return "/admin/coupon/add";
    }

    /**
     * 保存
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(Coupon coupon, Long[] productCategoryIds, Long[] productIds, RedirectAttributes redirectAttributes) {
        try {
            coupon.setProductCategories(new HashSet<ProductCategory>(productCategoryService.findList(productCategoryIds)));
            coupon.setProducts(new HashSet<Product>(productService.findList(productIds)));

            if (!isValid(coupon)) {
                return ERROR_VIEW;
            }
            if (coupon.getBeginDate() != null && coupon.getEndDate() != null && coupon.getBeginDate().after(coupon.getEndDate())) {
                return ERROR_VIEW;
            }
            if (coupon.getMinimumPrice() != null && coupon.getMaximumPrice() != null && coupon.getMinimumPrice().compareTo(coupon.getMaximumPrice()) > 0) {
                return ERROR_VIEW;
            }
            if (coupon.getIsExchange() && coupon.getPoint() == null) {
                return ERROR_VIEW;
            }
            if (!coupon.getIsExchange()) {
                coupon.setPoint(null);
            }
            coupon.setCouponCodes(null);
            coupon.setPromotions(null);
            coupon.setOrders(null);
            couponService.save(coupon);
            addFlashMessage(redirectAttributes, SUCCESS_MESSAGE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:list.htm";
    }

    /**
     * 编辑
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Long id, ModelMap model) {
        model.addAttribute("productCategories", productCategoryService.findAll());
        model.addAttribute("coupon", couponService.find(id));
        return "/admin/coupon/edit";
    }

    /**
     * 更新
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(Coupon coupon, Long[] productCategoryIds, Long[] productIds, RedirectAttributes redirectAttributes) {

        coupon.setProductCategories(new HashSet<ProductCategory>(productCategoryService.findList(productCategoryIds)));
        coupon.setProducts(new HashSet<Product>(productService.findList(productIds)));
        if (!isValid(coupon)) {
            return ERROR_VIEW;
        }
        if (coupon.getBeginDate() != null && coupon.getEndDate() != null && coupon.getBeginDate().after(coupon.getEndDate())) {
            return ERROR_VIEW;
        }

        if (coupon.getMinimumPrice() != null && coupon.getMaximumPrice() != null && coupon.getMinimumPrice().compareTo(coupon.getMaximumPrice()) > 0) {
            return ERROR_VIEW;
        }

        if (coupon.getIsExchange() && coupon.getPoint() == null) {
            return ERROR_VIEW;
        }
        if (!coupon.getIsExchange()) {
            coupon.setPoint(null);
        }
        couponService.update(coupon, "couponCodes", "promotions", "orders");
        addFlashMessage(redirectAttributes, SUCCESS_MESSAGE);
        return "redirect:list.htm";
    }

    /**
     * 列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Pageable pageable, ModelMap model) {
        model.addAttribute("page", couponService.findPage(pageable));
        return "/admin/coupon/list";
    }

    /**
     * 删除
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public
    @ResponseBody
    Message delete(Long[] ids) {
        couponService.delete(ids);
        return SUCCESS_MESSAGE;
    }

    /**
     * 生成优惠码
     */
    @RequestMapping(value = "/build", method = RequestMethod.GET)
    public String build(Long id, ModelMap model) {
        Coupon coupon = couponService.find(id);
        model.addAttribute("coupon", coupon);
        model.addAttribute("totalCount", couponCodeService.count(coupon, null, null, null, null));
        model.addAttribute("usedCount", couponCodeService.count(coupon, null, null, null, true));
        return "/admin/coupon/build";
    }

    /**
     * 下载优惠码
     */
    @RequestMapping(value = "/download", method = RequestMethod.POST)
    public ModelAndView download(Long id, Integer count, ModelMap model) {
        if (count == null || count <= 0) {
            count = 50;
        }
        Coupon coupon = couponService.find(id);
        List<CouponCode> data = couponCodeService.build(coupon, null, count);
        String filename = "coupon_code_" + new SimpleDateFormat("yyyyMM").format(new Date()) + ".xls";
        String[] contents = new String[4];
        contents[0] = message("admin.coupon.type") + ": " + coupon.getName();
        contents[1] = message("admin.coupon.count") + ": " + count;
        contents[2] = message("admin.coupon.operator") + ": " + adminService.getCurrentUsername();
        contents[3] = message("admin.coupon.date") + ": " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        return new ModelAndView(new ExcelView(filename, null, new String[]{"code"}, new String[]{message("admin.coupon.title")}, null, null, data, contents), model);
    }

    /**
     * 商品选择
     */
    @RequestMapping(value = "/product_select", method = RequestMethod.GET)
    public
    @ResponseBody
    List<Map<String, Object>> productSelect(String q) {
        List<Map<String, Object>> data = null;
        try {
            data = new ArrayList<Map<String, Object>>();
            if (StringUtils.isNotEmpty(q)) {
                List<Product> products = productService.search(q, 20);
                for (Product product : products) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("id", product.getId());
                    map.put("sn", product.getSn());
                    map.put("fullName", product.getName());
                    map.put("path", product.getPath());
                    data.add(map);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }
}